/**
 * @author  johon
 * @namespace 数据库操作封装
 */
var db = {
	/**
	 * 数据库名称
	 * @type String
	 */
	database: "LexinDB",
	/**
	 * 数据库版本
	 * @type String
	 */
	version: "1.0",
	/**
	 * 数据库空间
	 * @type Number
	 */
	space: 102400,
	/**
	 * 数据库描述
	 * @type String
	 */
	describe: "Lexin app",
	/**
	 * 数据库实例对象，初始化后创建
	 * @type Object
	 */
	db: null,
	/**
	 * 本地用户表名
	 * @type String  表名
	 */
	localUser :"local_users",
	/**
	 * 数据库初始化,所以表的创建已经更新字段操作，全放这里
	 * @param  Function callback 数据库初始化成功后回调方法
	 */
	init: function(callback) {
		this.db = openDatabase(this.database, this.version, this.describe, this.space);
		this.db.transaction(function(tx) {
			tx.executeSql("CREATE TABLE IF NOT EXISTS local_users(id text PRIMARY KEY,realname text,username text,password text,photo_src text,personal_word text,isPushed text,units text,haveSound text);");
			console.log("db init success");
			tx.executeSql('CREATE TABLE IF NOT EXISTS chat_u(id text,fid text,msg text,createtime text)',[]);
			tx.executeSql('CREATE TABLE IF NOT EXISTS office_news(id text PRIMARY KEY,name text,msg text,te INTEGER,red INTEGER,topT INTEGER,createtime text)',[]);
		},callback,callback);
	},
	/**
	 * 获取表字段数，只能手工添加
	 * @param tablename 表名
	 * @returns Number 字段数
	 */
	getTableColNum: function(tablename) {
		switch (tablename) {
			case "local_users":
				return 9;
			default:
				return 0;
		}
	},
	/**
	 * 保存数据，若数据已存在（根据主键判断），则更新，不存在，则插入。datas的数据顺序需与表字段顺序一致。
	 *
	 * @param String tablename 表名
	 * @param Array datas 保存的数据，null或数组，只保存一条数据，则为一维数据，若多条数据，则二维数组。
	 * @param Fucnction(tx,rs) callback 保存成功后回调方法
	 * @example  
	 * 使用方法：
	 * db.saveDatas("summarys", dataArr, null); 
	 */
	saveDatas: function(tablename, datas, callback) {
		if(datas.length==0){
			callback.call(null,null);
			return;
		}
		var colNum = this.getTableColNum(tablename);
		if (colNum == 0) {
			this.onerror("saveDate", "表名不存在！");
			return;
		}
		var sql = "replace into " + tablename;
		var colNum = this.getTableColNum(tablename);
		var args = new Array();
		var i = 0;
		while (i < colNum) {
			args.push("?");
			i++;
		}
		sql += " values(" + args.join() + ")";
		this.doQuery(sql, datas, callback);
	},
	/**
	 * 插入表数据（不查重）
	 *
	 * @param String tablename 表名
	 * @param Array columns 字段名，null或字符串数组
	 * @param Array datas 插入的数据，null或数组，只保存一条数据，则为一维数据，若多条数据，则二维数组。
	 * @param Function(tx,rs) callback 插入成功后回调方法
	 * @example
	 * 使用方法:
	 * 1、插入一条数据
	 * db.insertDatas(db.localUser,["id","username","password"],["1","xiaomi","123456"],function(tx,rs){
	 * 		成功插入后的执行方法
	 * });
	 * 2、插入多条数据
	 * datas=[["1","xiaomi","123456"],["2","xiaohong","123456"],["3","xiaoli","123456"]]
	 * db.insertDatas(db.localUser,["id","username","password"],datas,function(tx,rs){
	 * 		成功插入后的执行方法
	 * });
	 */
	insertDatas: function(tablename, columns, datas, callback) {
		if(datas instanceof Array && datas.length==0){
			callback.call(null,null);
			return;
		}
		if (columns != null && !columns instanceof Array) {
			this.onerror("insertSummary", "参数columns必须是数组或null");
			return;
		} else if (columns == null) {
			this.saveData(tablename, datas, callback);
		} else {
			var sql = "insert into " + tablename;
			var columnArgs = "";
			var args = new Array();
			var i = 0;
			while (i < columns) {
				args.push("?");
				i++;
			}
			sql += " (" + columns.join() + ") values (" + args.join() + ")";
			this.doQuery(sql, datas, callback);
		}
	},
	/**
	 * 更新数据
	 *
	 * @param String tablename 表名
	 * @param Array columns 字段名，null或字符串数组
	 * @param Array datas 要更新的字段值，字符串数组
	 * @param String where 查询条件
	 * @param Function(tx,rs) callback 更新数据后的回调
	 * @example
	 * 使用方法：
	 * db.updateDatas("summarys",["content","summary"], ["my content","my summary"], "id=32779",function(tx,rs){
	 * 		更新成功后执行操作方法
	 * });
	 */
	updateDatas: function(tablename, columns, datas, where, callback) {
		if((!datas instanceof Array && datas.length==0) ||columns == null||!columns instanceof Array){
			callback.call(null,null);
			return;
		}
		var sql = "update " + tablename + " set ";
		var args = "";
		args = columns.join("=?,") + "=?";
		where = where == null || where == "" ? "" : " and " + where;
		sql += args + " where 1=1 " + where;
		this.doQuery(sql, datas, callback);
	},
	/**
	 * 查找数据
	 *
	 * @param String tablename 表名
	 * @param Array columns 字段名，null或字符串数组
	 * @param String where 查询条件
	 * @param String orderby 排序，null，asc，desc，null或空则默认排序
	 * @param Function(tx,rs) callback 查找数据后的回调
	 * @example
	 * 使用方法：
	 * db.findDatas("summarys", ["id","content","summary"],"id='333'","date desc",function(tx,rs){
	 * 		console.log(rs.rows);
	 * 		for( var i = 0; i < rs.rows.length; i++){
	 * 			console.log(i);
	 * 			var item = rs.rows.item(i);
	 * 			console.log(item.id+":"+item.content+":"+item.summary+"\n");
	 * 		}
	 * });
	 */
	findDatas: function(tablename, columns, where, orderby, callback) {
		var sql = "select ";
		if (columns != null && columns instanceof Array) {
			sql += columns.join();
		} else {
			sql += " * ";
		}
		where = where == null || where == "" ? "" : " and " + where;
		orderby = orderby == null || orderby == "" ? "" : "order by " + orderby;
		sql += " from " + tablename + " where 1=1" + where + " " + orderby;
		this.doQuery(sql, null, callback);
	},
	/**
	 * 删除表数据
	 * @param String tablename 表名
	 * @param String where 条件
	 * @param Function(tx,rs) callback  删除数据后的回调
	 * @example
	 * 使用方法：
	 * db.deleteDatas(db.localUser,"id='23'",functin(tx,rs){
	 *       成功删除后执行的操作
	 * });
	 */
	deleteDatas: function(tablename, where, callback) {
		var sql = "delete from " + tablename + " where 1=1 ";
		where = where == null || where == "" ? "" : " and " + where;
		sql += where;
		this.doQuery(sql, null, callback);
	},
	/**
	 * 基础类执行sql，若未传回调方法，则成功后默认调用db.onsuccess
	 * sql执行出错，则默认调用db.onfail,会输出错误信息
	 *
	 * @param String sql sql语句
	 * @param Array datas null或数组，只保存一条数据，则为一维数据，若多条数据，则二维数组。
	 * @param Function(tx,rs) callback 执行sql后的回调
	 * @example
	 * 使用方法：
	 * 1、执行普通sql
	 * var sql="select * from localUser";
	 * db.doQuery(sql,null,function(tx,rs){
	 *    执行后的操作
	 * });
	 * 2、执行可传参数的sql
	 * var sql="select * from localUser where id=?";
	 * db.doQuery(sql,["123"],function(tx,rs){
	 *    执行后的操作
	 * });
	 */
	doQuery: function(sql, datas, callback) {
		var that = this;
		callback == null ? this.onsuccess : callback;
		var queue = function(tx, rs) {
			if (datas.length > 1) {
				tx.executeSql(sql, datas.pop(), queue, that.onfail);
			} else if (datas.length == 1) {
				tx.executeSql(sql, datas.pop(), callback, that.onfail);
			} else{
				callback.call(tx,rs);
			}
		};
		this.db.transaction(function(tx) {
			if (datas != null && datas instanceof Array) {
				for (var i in datas) {
					var data = datas[i];
					if (data instanceof Array) {
						tx.executeSql(sql, datas.pop(), queue, that.onfail);
						return;
						//tx.executeSql(sql, data, callback, this.onfail);
					} else {
						tx.executeSql(sql, datas, callback, that.onfail);
						return;
					}
				}
			} else {
				tx.executeSql(sql, [], callback, that.onfail);
			}
		});
	},
	/**
	 * 执行数据库异常时，调用
	 *
	 * @param Object tx transation事务对象
	 * @param Object err 异常对象
	 */
	onfail: function(tx,err) {		
		console.log("error:"+err.message);
	},
	/**
	 * 若代码执行异常时，调用
	 *
	 * @param String tag 标签
	 * @param String msg 出错信息
	 */
	onerror: function(tag, msg) {
		console.log(tag + ":" + msg);
	},
	/**
	 * sql执行成功后的默认调用方法
	 * @param  Object tx transation事务对象
	 * @param  Object rs 结果对象
	 */
	onsuccess: function(tx, rs) {
		console.log(rs);
	},
	/**
	 * 将结果对象转成json对象
	 * @param Object dataRow   查询数据库结果对象 rs.rows.item(n);
	 * @returns JSONObject json对象
	 * 
	 * @example
	 * 使用方法：
	 * var userInfo = rs.rows.item(0)
	 * app.currUser = db.parseToJson(userInfo);
	 * 
	 */
	parseToJson:function(dataRow){
		var jsonArray = new Array();
		$.each(dataRow,function(key,val){
			var valStr = "\""+val+"\"";
			var len = val.length;
			if(val=="\"\""){
				valStr = val;
			}else if(len>1 && val[0]=="[" && val[len-1]=="]"){
				try{
					if($.isArray(eval(val))) valStr=val;
				}catch(e){
					
				}
			}			
			jsonArray.push("\""+key+"\":"+valStr);
		});
		return JSON.parse("{"+jsonArray.join(",")+"}");
	}
};